package com.fingard.dsp.bank.directbank.psbc02;

import com.fingard.constant.Format;
import com.fingard.dsp.bank.directConfig.ActSetItem;
import com.fingard.dsp.bank.directbank.FailCode;
import com.fingard.dsp.bank.directbank.PaymentState;
import com.fingard.dsp.bank.directbank.bankInterface.IBatPayRec;
import com.fingard.dsp.bank.directbank.psbc02.util.MessageUtil;
import com.fingard.dsp.bank.reqrespobj.batpayrec.ReqBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.ReqQryBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.RetAtsBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.RetAtsQryBatPayRec;
import com.fingard.text.StringHelper;
import com.fingard.xml.XmlReadMode;
import com.fingard.xml.XmlTextReader;
import org.w3c.dom.Document;

import javax.crypto.CipherOutputStream;
import java.security.PrivateKey;

public class PSBC02BatPayRec extends PSBC02Base implements IBatPayRec {
    @Override
    public RetAtsBatPayRec d_1988_BatPay(ReqBatPayRec p_req1988) throws Exception {
        return d_BatPayRec(p_req1988);
    }

    @Override
    public RetAtsQryBatPayRec d_1998_QryBatPay(ReqQryBatPayRec p_req1998) throws Exception {
        return d_QryBatPayRec(p_req1998);
    }

    @Override
    public RetAtsBatPayRec d_9188_BatPay(ReqBatPayRec p_req9188) throws Exception {
        return d_BatPayRec(p_req9188);
    }

    @Override
    public RetAtsQryBatPayRec d_9198_QryBatPay(ReqQryBatPayRec p_req9198) throws Exception {
        return d_QryBatPayRec(p_req9198);
    }

    public RetAtsBatPayRec d_BatPayRec(ReqBatPayRec p_reqBat) throws Exception {
        RetAtsBatPayRec retAts = new RetAtsBatPayRec(p_reqBat.reqHeader);
        retAts.reqSeqID = p_reqBat.reqBatchNO;

        try {
            ActSetItem actItem = getBankConfig().getActSetItem(p_reqBat.ownAct, "");
            if (actItem == null ) {
                retAts.respCode = "0";
                retAts.respInfo = "未找到账号[" + p_reqBat.ownAct + "]商户配置信息!";
                retAts.reqSeqID = p_reqBat.reqBatchNO;
                retAts.transState = PaymentState.FAIL_Batch;
                retAts.payInfoCode = FailCode.E9981;
                retAts.writeRetToATS();
                return retAts;
            }


            StringBuilder messageBody = new StringBuilder();
            while(p_reqBat.readRecord()) {
                messageBody.append("<CPAReq id=\""+PSBC02TransCode.deal_918801_CPAReq+"\">\r\n");
                messageBody.append("<version>1.0.1</version>\r\n");
                messageBody.append("<instId>"+bankFront.org+"</instId>\r\n");
                messageBody.append("<certId>"+bankFront.keyID+"</certId>\r\n");
                messageBody.append("<merchantCode>"+actItem.merchantId+"</merchantCode>\r\n");
                messageBody.append("<date>"+ Format.DateTimeFormat.format(p_reqBat.readedDetail.getPayDateTime()).replace("-","")+"</date>\r\n");
                messageBody.append("<serialNo>"+p_reqBat.readedDetail.askNumber+"</serialNo>\r\n");
                messageBody.append("<signNo>"+p_reqBat.readedDetail.authCode+"</signNo>\r\n");

                String cardType = "D";
                if ("1".equalsIgnoreCase(p_reqBat.readedDetail.cardType)) {
                    cardType = "B";
                } else if ("3".equalsIgnoreCase(p_reqBat.readedDetail.cardType) || "4".equalsIgnoreCase(p_reqBat.readedDetail.cardType)) {
                    cardType = "C";
                }
                messageBody.append("<cardType>"+cardType+"</cardType>\r\n");
                messageBody.append("<charge>00</charge>\r\n");
                messageBody.append("<amount>"+StringHelper.amountMultiply100(p_reqBat.readedDetail.payAmount)+"</amount>\r\n");
                messageBody.append("<currency>156</currency>\r\n");
                messageBody.append("<expiryDate/>\r\n");
                messageBody.append("<cvv2/>\r\n");
                messageBody.append("</CPAReq>");
            }
            StringBuilder messageRequest = new StringBuilder();
            messageRequest.append("<PSBC>\r\n");
            messageRequest.append("<Message id=\""+getQryTransID()+"\">\r\n");
            messageRequest.append(messageBody).append("\r\n");
            messageRequest.append("</Message>\r\n");
            messageRequest.append("</PSBC>\r\n");

            PrivateKey privateKey = readPrivateKey(actItem.ownKeyStorePath, actItem.ownKeyPassword);
            Document document = MessageUtil.getXml(messageRequest.toString());
            String tmpStrReq = MessageUtil.xmlSign(document, privateKey, "CPAReq");

            String[] tmpRetStr = sendToBank(tmpStrReq);

            if(tmpRetStr[0].length() == 0) {
                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpRetStr[1], tmpSbMsg);
                if (tmpBkReader != null) {
                    if (tmpBkReader.read("/PSBC/Message/Error")) {
                        String tmpRespCode = tmpBkReader.readedXElement.getSingleText("errorCode");
                        String tmpRespInfo = tmpBkReader.readedXElement.getSingleText("errorMessage") + "-" + tmpBkReader.readedXElement.getSingleText("errorDetail");
                        retAts.respCode = "0";
                        retAts.respInfo = tmpRespInfo;
                        retAts.transState = tmpRespCode;
                        retAts.payInfoCode = tmpRespCode;
                    }
                    tmpBkReader.resetReadMode(XmlReadMode.XElementReader);
                    if (tmpBkReader.read("/PSBC/Message/CPARes")) {
                        retAts.respCode = "0";
                        retAts.transState = "SUCCESS";
                        retAts.payInfoCode = "SUCCESS";
                    }
                } else {
                    retAts.respCode = "-1";
                    retAts.respInfo = tmpSbMsg.toString();
                }
            } else {
                retAts.respCode = "-1";
                retAts.respInfo = tmpRetStr[1];
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            retAts.respCode = "-1";
            retAts.respInfo = ex.getMessage();
            WriteBankLogLn(ex);
        }

        retAts.writeRetToATS();
        return retAts;
    }

    public RetAtsQryBatPayRec d_QryBatPayRec(ReqQryBatPayRec p_reqQryBat) throws Exception {
        return null;
    }
}